import json
from re import X
from channels.generic.websocket import WebsocketConsumer,AsyncWebsocketConsumer
from channels.db import database_sync_to_async
from django.forms import model_to_dict
from django.db.models import Q
from website_server.models import RoomTab, RoomUserTab, UserinfoTab
from website_server.utils import CJsonEncoder, getTime, model_to_list

class ChatConsumer(AsyncWebsocketConsumer):
  # 建立连接
  async def connect(self):
    self.room_name = self.scope['url_route']['kwargs']['room_name']
    self.room_group_name = 'chat_%s' % self.room_name
    if self.is_login() and await self.get_room_name():
      print('正在连接...')
      await self.channel_layer.group_add(self.room_group_name,self.channel_name)
      await self.create_room_user()
      await self.accept()
      
    else:
      print('连接失败')

  # 断开连接
  async def disconnect(self, close_code):
    await self.channel_layer.group_discard(self.room_group_name,self.channel_name)
    await self.delete_room_user()
    await self.channel_layer.group_send(self.room_group_name,{'type': 'chat_user'})
  
  # 接收心跳
  async def receive(self, text_data):
    text_data_json = json.loads(text_data)
    message = text_data_json['message']
    if message['key'] == 101: # 接收聊天消息
      await self.channel_layer.group_send(self.room_group_name,{'type': 'chat_message','message': message})
    elif message['key'] == 102: # 用户进入
      await self.channel_layer.group_send(self.room_group_name,{'type': 'chat_user'})
    elif message['key'] == 103: # 解散房间
      await self.channel_layer.group_send(self.room_group_name,{'type': 'chat_remove'})

  # 101发送聊天事件
  async def chat_message(self, event):
    username = event['message']['username']
    content = event['message']['content']
    userinfo = await self.get_user_info(username)
    if userinfo:
      result = {
        'content': content,
        **userinfo,
        'sendTime': getTime(),
        'key': 101
      }
      await self.send(text_data=json.dumps(result,cls=CJsonEncoder))
    else:
      await self.send(text_data=json.dumps({'key':500}))

  # 102发送用户列表
  async def chat_user(self,event):
    userList = await self.get_room_user()
    result = {'data': userList,'key': 102}
    await self.send(text_data=json.dumps(result,cls=CJsonEncoder))

  # 103解散房间事件
  async def chat_remove(self,event):
    await self.delete_room()
    result = {'key': 103}
    await self.send(text_data=json.dumps(result))

  # 登录验证
  def is_login(self):
    print('登陆验证...')
    if self.scope['session'] and self.scope['session']['user']:
      self.scope['user'] = self.scope['session']['user']
      return True
    else:
      self.close()
      return False
      
  # 获取房间信息
  @database_sync_to_async
  def get_room_name(self):
    print('正在获取房间信息...')
    return RoomTab.objects.filter(chatid=self.room_name).first()

  # 用户进入
  @database_sync_to_async
  def create_room_user(self):
    username = self.scope['user']
    print(username + '进入房间...')
    user = RoomUserTab.objects.filter(chatid=self.room_name,username=username)
    if username and len(user)==0:
      RoomUserTab.objects.create(
        chatid = RoomTab.objects.filter(chatid=self.room_name).first(),
        username = UserinfoTab.objects.filter(username=username).first(),
        time = getTime()
      )
    else:
      # 更新用户进入时间
      if user:
        user.update(time=getTime())

  # 用户离开
  @database_sync_to_async
  def delete_room_user(self):
    username = self.scope['user']
    RoomUserTab.objects.filter(chatid=self.room_name,username=username).delete()
    print(username + '离开...')
  
  # 房主解散房间
  @database_sync_to_async
  def delete_room(self):
    RoomTab.objects.filter(chatid=self.room_name).delete()
    print('房间号:' + self.room_name + '已解散...')

  # 获取发消息者信息
  @database_sync_to_async
  def get_user_info(self,username):
    userinfo = RoomUserTab.objects.filter(chatid=self.room_name,username=username).first()
    if userinfo:
      return model_to_dict(UserinfoTab.objects.filter(username=username).first())
    else:
      return False

  # 获取房间所有用户
  @database_sync_to_async
  def get_room_user(self):
    userList = RoomUserTab.objects.filter(chatid=self.room_name).order_by('-time')
    result = [{
      **model_to_dict(x.username)
    } for x in userList]
    return result
